/*
 * Copyright 2008-2009 Daniel Cachapa <cachapa@gmail.com>
 * 
 * This program is distributed under the terms of the GNU General Public Licence Version 3
 * The licence can be read in its entirety in the LICENSE.txt file accompaning this source code,
 * or at: http://www.gnu.org/copyleft/gpl.html
 * 
 * This file is part of WeightWatch.
 *
 * WeightWatch is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * WeightWatch is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the WeightWatch source code. If not, see
 * <http://www.gnu.org/licenses/>.
 */


import com.sun.lwuit.Button;
import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Container;
import com.sun.lwuit.Dialog;
import com.sun.lwuit.Display;
import com.sun.lwuit.Graphics;
import com.sun.lwuit.Label;
import com.sun.lwuit.Painter;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.events.DataChangedListener;
import com.sun.lwuit.geom.Rectangle;
import com.sun.lwuit.layouts.FlowLayout;

public class DateField extends Button implements ActionListener {
	private Component parent;
	private long time;
	private DateSelector dateSelector;
	private Command setCommand;
	private Command cancelCommand;
	private DataChangedListener dataChangedListener = null;

	public DateField(Component parent) {
		this.parent = parent;
		this.time = System.currentTimeMillis();
		this.setAlignment(CENTER);
		MyDate date = new MyDate(this.time);
                this.getSelectedStyle().setBgColor(0x00ccffcc);
		this.setText(date.toShortString());
		
		this.setCommand = new Command("Ok");
		this.cancelCommand = new Command("Cancel");
		
		this.dateSelector = new DateSelector(this.time);
		this.dateSelector.getContentPane().getStyle().setBgTransparency(0);
		this.dateSelector.addCommand(setCommand);
		this.dateSelector.setDefaultCommand(setCommand);
		this.dateSelector.addCommand(cancelCommand);
		this.dateSelector.setBackCommand(cancelCommand);
		
		this.addActionListener(this);
	}

	public void addDataChangeListener(DataChangedListener dataChangedListener) {
		this.dataChangedListener = dataChangedListener;
	}

	public long getTime() {
		return time;
	}

	public void setTime(long time) {
		this.time = time;
		this.setText(new MyDate(time).toShortString());
		this.dateSelector.setTime(time);
	}

	public void actionPerformed(ActionEvent ae) {
		Command result = dateSelector.showDialog();
		
		if (result == setCommand) {
			this.time = dateSelector.getTime();
			this.setText(new MyDate(time).toShortString());
			parent.repaint(); // The size of the button might have changed
			if (dataChangedListener != null) {
				this.dataChangedListener.dataChanged(TOP, TOP);
			}
		}
		else if (result == cancelCommand) {
			// Do nothing
		}
	}
	
	private class DateSelector extends Dialog {
                private int day, month, year;
                private Label dayLabel, monthLabel, yearLabel;

                public DateSelector(long time) {
                        MyDate date = new MyDate(time);
                        this.setTitle("Enter date");
                        this.day = date.getDay();
                        this.month = date.getMonth();
                        this.year = date.getYear();

                        this.getTitleStyle().setFgColor(0x00dddddd);
                        this.getTitleStyle().setBgPainter(new Painter() {
                                public void paint(Graphics g, Rectangle rect) {
                                        g.setColor(0x00777777);
                                        g.fillRoundRect(rect.getX(), rect.getY(),
                                                 rect.getSize().getWidth(), rect.getSize().getHeight(), 12, 12);
                                }
                        });

                        this.getContentPane().setLayout(new FlowLayout(Component.CENTER));

                        Container container = new Container();
                        container.getStyle().setBgPainter(new Painter() {
                                public void paint(Graphics g, Rectangle rect) {
                                        g.setColor(0x00888888);
                                        g.fillRoundRect(rect.getX(), rect.getY(),
                                                 rect.getSize().getWidth(), rect.getSize().getHeight(), 12, 12);
                                }
                        });

                        this.dayLabel = new Label(this.day+"");
                        this.dayLabel.getStyle().setBgColor(0x00888888);
                        this.dayLabel.setFocusable(true);

                        this.monthLabel = new Label(date.getShortMonthName());
                        this.monthLabel.getStyle().setBgColor(0x00888888);
                        this.monthLabel.setFocusable(true);

                        this.yearLabel = new Label(this.year+"");
                        this.yearLabel.getStyle().setBgColor(0x00888888);
                        this.yearLabel.setFocusable(true);

                        container.addComponent(this.dayLabel);
                        container.addComponent(this.monthLabel);
                        container.addComponent(this.yearLabel);

                        this.addComponent(container);
                }

                public long getTime() {
                        return new MyDate(day, month, year).getTime();
                }

                public void setTime(long time) {
                        MyDate date = new MyDate(time);
                        this.day = date.getDay();
                        this.month = date.getMonth();
                        this.year = date.getYear();
                        this.dayLabel.setText(this.day+"");
                        this.monthLabel.setText(date.getShortMonthName());
                        this.year = date.getYear();
                        this.yearLabel.setText(this.year+"");
                }

                private void increaseValue() {
                        int maxDays;

                        if (dayLabel.hasFocus()) {
                                this.day++;
                                maxDays = MyDate.getDaysInMonth(month, year);
                                if (this.day > maxDays) this.day = 1;
                                dayLabel.setText(this.day+"");
                        }

                        else if (monthLabel.hasFocus()) {
                                this.month++;
                                if (this.month > 12) this.month = 1;
                                maxDays = MyDate.getDaysInMonth(month, year);
                                monthLabel.setText(MyDate.getShortMonthName(month));
                                if (this.day > maxDays) {
                                        this.day = maxDays;
                                        dayLabel.setText(this.day+"");
                                }
                        }

                        else if (yearLabel.hasFocus()) {
                                this.year++;
                                maxDays = MyDate.getDaysInMonth(month, year);
                                yearLabel.setText(this.year+"");
                                if (this.day > maxDays) {
                                        this.day = maxDays;
                                        dayLabel.setText(this.day+"");
                                }
                        }
                        this.repaint();
                }

                private void decreaseValue() {
                        int maxDays;

                        if (dayLabel.hasFocus()) {
                                this.day--;
                                maxDays = MyDate.getDaysInMonth(month, year);
                                if (this.day < 1) this.day = maxDays;
                                dayLabel.setText(this.day+"");
                        }

                        else if (monthLabel.hasFocus()) {
                                this.month--;
                                if (this.month < 1) this.month = 12;
                                maxDays = MyDate.getDaysInMonth(month, year);
                                monthLabel.setText(MyDate.getShortMonthName(month));
                                if (this.day > maxDays) {
                                        this.day = maxDays;
                                        dayLabel.setText(this.day+"");
                                }
                        }

                        else if (yearLabel.hasFocus()) {
                                this.year--;
                                maxDays = MyDate.getDaysInMonth(month, year);
                                yearLabel.setText(this.year+"");
                                if (this.day > maxDays) {
                                        this.day = maxDays;
                                        dayLabel.setText(this.day+"");
                                }
                        }
                        this.repaint();
                }

                public void keyPressed(int keyCode) {
                        int k = Display.getInstance().getGameAction(keyCode);
                        switch (k) {
                                case Display.GAME_UP:
                                        increaseValue();
                                        break;

                                case Display.GAME_DOWN:
                                        decreaseValue();
                                        break;

                                default:
                                        super.keyPressed(keyCode);
                        }
                }
	}
}
